# file: services/llm_service.py

from langchain_openai import ChatOpenAI
from abc import ABC, abstractmethod
import json
from config.settings import settings


class BaseLLM(ABC):
    """LLM服务的基类"""

    def __init__(self):
        self.llm = None

    @abstractmethod
    def _initialize_llm(self):
        """初始化具体的LLM实例"""
        pass

    def generate_json(self, prompt):
        """
        使用LLM模型生成JSON格式的响应（同步方法）

        Args:
            prompt (str): 输入的提示词

        Returns:
            dict: 包含回答、来源和风险提示的字典
        """
        try:
            # 调用模型生成响应
            response = self.llm.invoke(prompt)
            response_text = response.content

            # 尝试解析为JSON，如果失败则构建标准格式
            try:
                response_data = json.loads(response_text)
                # 确保必要字段存在
                if "answer" not in response_data:
                    response_data["answer"] = response_text
            except json.JSONDecodeError:
                # 如果不是有效的JSON，构建标准响应格式
                response_data = {
                    "answer": response_text,
                    "sources": [],
                    "risk_disclaimer": "以上内容仅供参考，不构成投资建议。投资有风险，入市需谨慎。"
                }

            return response_data

        except Exception as e:
            # 错误处理
            return {
                "answer": f"抱歉，处理您的请求时出现错误: {str(e)}",
                "sources": [],
                "risk_disclaimer": "以上内容仅供参考，不构成投资建议。投资有风险，入市需谨慎。"
            }

    async def agenerate_json(self, prompt):
        """
        异步调用LLM模型生成JSON格式的响应

        Args:
            prompt (str): 输入的提示词

        Returns:
            dict: 包含回答、来源和风险提示的字典
        """
        try:
            # 异步调用模型生成响应
            response = await self.llm.ainvoke(prompt)
            response_text = response.content

            # 尝试解析为JSON，如果失败则构建标准格式
            try:
                response_data = json.loads(response_text)
                # 确保必要字段存在
                if "answer" not in response_data:
                    response_data["answer"] = response_text
            except json.JSONDecodeError:
                # 如果不是有效的JSON，构建标准响应格式
                response_data = {
                    "answer": response_text,
                    "sources": [],
                    "risk_disclaimer": "以上内容仅供参考，不构成投资建议。投资有风险，入市需谨慎。"
                }

            return response_data

        except Exception as e:
            # 错误处理
            return {
                "answer": f"抱歉，处理您的请求时出现错误: {str(e)}",
                "sources": [],
                "risk_disclaimer": "以上内容仅供参考，不构成投资建议。投资有风险，入市需谨慎。"
            }


class DeepSeekLLM(BaseLLM):
    """DeepSeek LLM的具体实现"""

    def _initialize_llm(self):
        """初始化DeepSeek LLM实例"""
        self.llm = ChatOpenAI(
            api_key=settings.DEEPSEEK_API_KEY,
            base_url="https://api.deepseek.com/v1",
            model="deepseek-chat",
            temperature=0.3,
            max_tokens=1024
        )

    def __init__(self):
        super().__init__()
        self._initialize_llm()


# 创建实例供外部使用
deepseek_llm = DeepSeekLLM()
